home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWFiles / SLFilRep.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  23.6 KB  |  908 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                SLFilRep.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWEXCDEF_H
  13. #include "FWExcDef.h"
  14. #endif
  15.  
  16. #ifndef FWFILE_H
  17. #include "FWFileSy.h"
  18. #endif
  19.  
  20. #ifndef FWFILESP_H
  21. #include "FWFileSp.h"
  22. #endif
  23.  
  24. #ifndef FWSOMENV_H
  25. #include "FWSOMEnv.h"
  26. #endif
  27.  
  28. #if defined(FW_BUILD_WIN) && !defined(__WINDOWS_H)
  29. #include <windows.h>
  30. #endif
  31.  
  32. #include <Limits.h>
  33.  
  34. #ifndef FWPRIDEB_H
  35. #include "FWPriDeb.h"
  36. #endif
  37.  
  38. #ifndef FWEXCDEF_H
  39. #include "FWExcDef.h"
  40. #endif
  41.  
  42. #ifndef FWEXCEPT_H
  43. #include "FWExcept.h"
  44. #endif
  45.  
  46. #if defined(FW_BUILD_MAC) && !defined(__FILES__)
  47. #include "Files.h"
  48. #endif
  49.  
  50. #if defined(FW_BUILD_WIN) && !defined(IO_H)
  51. #include "io.h"
  52. #endif
  53.  
  54. /*
  55.  *  This file was generated by the SOM Compiler.
  56.  *  Generated using: 
  57.  *      SOM Emitter emitxtm.dll: 2.33
  58.  */
  59.  
  60. #define FW_OFile_Class_Source
  61. #include "SLFilRep.xih"
  62.  
  63. #ifdef FW_BUILD_MAC
  64. #pragma segment File
  65. #endif
  66.  
  67. #ifdef FW_BUILD_WIN16
  68. extern "C" void FAR PASCAL DOS3Call();                // We use this instead of calling "Int 21h"
  69. #endif
  70.  
  71.  
  72. //----------------------------------------------------------------------------------------
  73. // Forward definitions
  74. //----------------------------------------------------------------------------------------
  75.  
  76. static void privOpenFile(FW_OFile *somSelf, Environment *ev, FW_Boolean allowCreate);
  77. static void privCloseFile(FW_OFile *somSelf, Environment *ev);
  78. static void privDoRead(FW_OFile *somSelf, Environment *ev, void* destination, long count);
  79. static void privDoWrite(FW_OFile *somSelf, Environment *ev, const void* source, long count);
  80.  
  81. #ifdef FW_BUILD_WIN
  82. static short privWinGetIOBufferSize(long bytesDesired, const void* buffer);
  83. static FW_PlatformError privWinPrimitiveRead(FW_PlatformFileHandle handle,
  84.                                                     short bytesToRead,
  85.                                                     void* buffer,
  86.                                                     short& bytesActuallyRead);
  87. static FW_PlatformError privWinPrimitiveWrite(FW_PlatformFileHandle handle,
  88.                                                      short bytesToWrite,
  89.                                                      const void* buffer,
  90.                                                      short& bytesActuallyWritten);
  91.  
  92. static FW_PlatformError privWinMoveFilePointer(FW_OFile *somSelf, 
  93.                                                       Environment *ev,
  94.                                                       long markOffset,
  95.                                                       FW_EFS_MoveMethods positioningMode,
  96.                                                       long& newPosition);
  97. #endif
  98.  
  99.  
  100. //========================================================================================
  101. // struct FW_CPrivFileRep
  102. //    This struct contains the body of the file representation
  103. //========================================================================================
  104.  
  105. class FW_CPrivFileRep
  106. {
  107. public:
  108.     FW_DECLARE_AUTO(FW_CPrivFileRep)
  109.  
  110.     FW_CPrivFileRep(Environment *ev,
  111.                     FW_OFileSpecification* fileSpecification);
  112.     FW_CPrivFileRep(Environment *ev,
  113.                     FW_OFileSpecification* fileSpecification, 
  114.                     FW_SAccessPermission* permission);
  115.  
  116.     ~FW_CPrivFileRep();
  117.  
  118.     FW_OFileSpecification*        fFileSpec;
  119.     FW_SAccessPermission        fPermission;
  120.     FW_PlatformFileHandle        fFileHandle;
  121. };
  122.  
  123.  
  124. FW_DEFINE_AUTO(FW_CPrivFileRep)
  125.  
  126. //----------------------------------------------------------------------------------------
  127. // FW_CPrivFileRep::FW_CPrivFileRep
  128. //----------------------------------------------------------------------------------------
  129.  
  130. inline FW_CPrivFileRep::FW_CPrivFileRep(Environment *ev,
  131.                                         FW_OFileSpecification* fileSpecification) :
  132.     fFileHandle(0)
  133. {
  134.     fPermission.fAccess = FW_kReadWrite;
  135.     fPermission.fDeny   = FW_kDenyReadWrite;
  136.     fFileSpec = new FW_OFileSpecification;
  137.     fFileSpec->AssignOFileSpecification(ev, fileSpecification);
  138.  
  139.     FW_END_CONSTRUCTOR
  140. }
  141.  
  142.  
  143. inline FW_CPrivFileRep::FW_CPrivFileRep(Environment *ev,
  144.                                         FW_OFileSpecification* fileSpecification, 
  145.                                         FW_SAccessPermission* permission) :
  146.     fPermission(*permission),
  147.     fFileHandle(0)
  148. {
  149.     fFileSpec = new FW_OFileSpecification;
  150.     fFileSpec->AssignOFileSpecification(ev, fileSpecification);
  151.  
  152.     FW_END_CONSTRUCTOR
  153. }
  154.  
  155.  
  156. //----------------------------------------------------------------------------------------
  157. // FW_CPrivFileRep::~FW_CPrivFileRep
  158. //----------------------------------------------------------------------------------------
  159.  
  160. inline FW_CPrivFileRep::~FW_CPrivFileRep()
  161. {
  162.     FW_START_DESTRUCTOR
  163.     delete fFileSpec;
  164. }
  165.  
  166.  
  167.  
  168. //----------------------------------------------------------------------------------------
  169. //    FW_OFile__InitWithExclusiveAccess
  170. //  Open with exclusive access
  171. //----------------------------------------------------------------------------------------
  172.  
  173. SOM_Scope void  SOMLINK FW_OFile__InitWithExclusiveAccess(FW_OFile *somSelf, Environment *ev,
  174.         FW_OFileSpecification* fileSpecification,
  175.         FW_Boolean allowCreate)
  176. {
  177.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  178.  
  179.     FW_SOM_TRY
  180.     {
  181.         somThis->fRep = FW_NEW(FW_CPrivFileRep, (ev, fileSpecification));
  182.         privOpenFile(somSelf, ev, allowCreate);
  183.     }
  184.     FW_SOM_CATCH
  185. }
  186.  
  187.  
  188. //----------------------------------------------------------------------------------------
  189. //    FW_OFile__InitWithPermissions
  190. //  Open with specified permissions.
  191. //----------------------------------------------------------------------------------------
  192.  
  193. SOM_Scope void  SOMLINK FW_OFile__InitWithPermissions(FW_OFile *somSelf, Environment *ev,
  194.         FW_OFileSpecification* fileSpecification,
  195.         FW_SAccessPermission* permission,
  196.         FW_Boolean allowCreate)
  197. {
  198.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  199.  
  200.     FW_SOM_TRY
  201.     {
  202.         somThis->fRep = FW_NEW(FW_CPrivFileRep, (ev, fileSpecification, permission));
  203.         privOpenFile(somSelf, ev, allowCreate);
  204.     }
  205.     FW_SOM_CATCH
  206. }
  207.  
  208.  
  209. //----------------------------------------------------------------------------------------
  210. //    FW_OFile__Read
  211. //  Read 'count' bytes from current position to 'destination' and
  212. //  increment current position by 'count'.
  213. //----------------------------------------------------------------------------------------
  214.  
  215. SOM_Scope void  SOMLINK FW_OFile__Read(FW_OFile *somSelf, Environment *ev,
  216.         void* destination,
  217.         long count)
  218. {
  219.     FW_SOM_TRY
  220.     {
  221.         privDoRead(somSelf, ev, destination, count);
  222.     }
  223.     FW_SOM_CATCH
  224. }
  225.  
  226.  
  227. //----------------------------------------------------------------------------------------
  228. //    FW_OFile__Write
  229. //  Write 'count' bytes from 'source' to current file position.
  230. //----------------------------------------------------------------------------------------
  231.  
  232. SOM_Scope void  SOMLINK FW_OFile__Write(FW_OFile *somSelf, Environment *ev,
  233.         void* source,
  234.         long count)
  235. {
  236.     FW_SOM_TRY
  237.     {
  238.         privDoWrite(somSelf, ev, source, count);
  239.     }
  240.     FW_SOM_CATCH
  241. }
  242.  
  243.  
  244. //----------------------------------------------------------------------------------------
  245. //    FW_OFile__GetLength
  246. //  Return the logical size of the file.
  247. //----------------------------------------------------------------------------------------
  248.  
  249. SOM_Scope long  SOMLINK FW_OFile__GetLength(FW_OFile *somSelf, Environment *ev)
  250. {
  251.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  252.  
  253.     FW_SOM_TRY
  254.     {
  255.         FW_CPrivFileRep& rep = *somThis->fRep;
  256.         long length;
  257.  
  258. #ifdef FW_BUILD_WIN
  259.         // Since Windows does not support this feature directly, we have to reset the file
  260.         //   pointer to get the length and then restore the original position.
  261.         long oldPosition = somSelf->GetPosition(ev);
  262.         FW_FailOnError(privWinMoveFilePointer(somSelf, ev, 0, FW_kFromEnd, length));
  263.         FW_FailOnError(privWinMoveFilePointer(somSelf, ev, oldPosition, FW_kFromStart, oldPosition));
  264. #endif
  265.  
  266. #ifdef FW_BUILD_MAC
  267.         long macEOF;
  268.     
  269.         FW_FailOnError(::GetEOF(rep.fFileHandle, &macEOF));
  270.         length = macEOF;
  271. #endif
  272.  
  273.         return length;
  274.     }
  275.     FW_SOM_CATCH
  276.     return 0;
  277. }
  278.  
  279.  
  280. //----------------------------------------------------------------------------------------
  281. //    FW_OFile__SetLength
  282. //  Return the logical size of the file.
  283. //----------------------------------------------------------------------------------------
  284.  
  285. SOM_Scope void  SOMLINK FW_OFile__SetLength(FW_OFile *somSelf, Environment *ev,
  286.         long length)
  287. {
  288.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  289.  
  290.     FW_SOM_TRY
  291.     {
  292.         FW_CPrivFileRep& rep = *somThis->fRep;
  293.         FW_PlatformError theError = FW_xNoError;
  294.         long currentLength = somSelf->GetLength(ev);
  295.  
  296. #ifdef FW_BUILD_WIN16
  297.         long oldPosition = somSelf->GetPosition(ev);
  298.         FW_FailOnError(privWinMoveFilePointer(somSelf, ev, length, FW_kFromStart, length));
  299.         
  300.         // writing 0 bytes truncates the file at the current position
  301.         char buf;
  302.         short actualWritten;
  303.         FW_PlatformError writeError = privWinPrimitiveWrite(rep.fFileHandle, 0, &buf, actualWritten);
  304.         
  305.         // move back to the old position, regardless of whether the write was successfull
  306.         if (oldPosition > length)
  307.             oldPosition = length;
  308.         FW_PlatformError seekError = privWinMoveFilePointer(somSelf, ev, oldPosition, FW_kFromStart, oldPosition);
  309.         
  310.         if (writeError != FW_xNoError)
  311.             FW_FailOnError(writeError);
  312.         else
  313.             FW_FailOnError(seekError);
  314. #endif
  315.     
  316. #ifdef FW_BUILD_WIN32
  317.         long oldPosition = somSelf->GetPosition(ev);
  318.         somSelf->SetPosition(ev, FW_kFromStart, length);
  319.         if (!::SetEndOfFile(rep.fFileHandle))
  320.             theError = ::GetLastError();
  321.         somSelf->SetPosition(ev, FW_kFromStart, oldPosition);
  322. #endif
  323.     
  324. #ifdef FW_BUILD_MAC
  325.         theError = ::SetEOF(rep.fFileHandle, length);
  326. #endif
  327.     
  328.         FW_FailOnError(theError);
  329.     }
  330.     FW_SOM_CATCH
  331. }
  332.  
  333.  
  334. //----------------------------------------------------------------------------------------
  335. //    FW_OFile__GetPosition
  336. //  Return current file position.
  337. //----------------------------------------------------------------------------------------
  338.  
  339. SOM_Scope long  SOMLINK FW_OFile__GetPosition(FW_OFile *somSelf, Environment *ev)
  340. {
  341.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  342.  
  343.     FW_SOM_TRY
  344.     {
  345.         FW_CPrivFileRep& rep = *somThis->fRep;
  346.         FW_PlatformError theError = FW_xNoError;
  347.         long currentPosition;
  348.     
  349. #ifdef FW_BUILD_WIN
  350.         theError = privWinMoveFilePointer(somSelf, ev, 0, FW_kFromCurrent, currentPosition);
  351. #endif
  352.     
  353. #ifdef FW_BUILD_MAC
  354.         theError = ::GetFPos(rep.fFileHandle, ¤tPosition);
  355. #endif
  356.     
  357.         FW_FailOnError(theError);
  358.         return currentPosition;
  359.     }
  360.     FW_SOM_CATCH
  361.     return 0;
  362. }
  363.  
  364.  
  365. //----------------------------------------------------------------------------------------
  366. //    FW_OFile__SetPosition
  367. //  Set current file position using mode.
  368. //----------------------------------------------------------------------------------------
  369.  
  370. SOM_Scope void  SOMLINK FW_OFile__SetPosition(FW_OFile *somSelf, Environment *ev,
  371.         long positioningMode,
  372.         long markOffset)
  373. {
  374.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  375.  
  376.     FW_SOM_TRY
  377.     {
  378.         FW_CPrivFileRep& rep = *somThis->fRep;
  379.         FW_PlatformError theError = FW_xNoError;
  380.         
  381. #ifdef FW_BUILD_WIN
  382.         theError = privWinMoveFilePointer(somSelf, ev, markOffset, (FW_EFS_MoveMethods)positioningMode, markOffset);
  383. #endif
  384.     
  385. #ifdef FW_BUILD_MAC
  386.         long newLength = markOffset;
  387.         theError = ::SetFPos(rep.fFileHandle, positioningMode, newLength);
  388. #endif
  389.     
  390. #ifdef FW_BUILD_WIN16
  391.         // Win16 returns this error to indicate an invalid positioningMode.
  392.         if (theError == FW_kPermissionError)
  393.             theError = FW_kParameterError;
  394. #endif
  395.     
  396.         FW_FailOnError(theError);
  397.     }
  398.     FW_SOM_CATCH
  399. }
  400.  
  401.  
  402. //----------------------------------------------------------------------------------------
  403. //    FW_OFile__BytesToEndOfFile
  404. //  Returns the number of bytes from the current position to the
  405. //    end of the file.
  406. //----------------------------------------------------------------------------------------
  407.  
  408. SOM_Scope long  SOMLINK FW_OFile__BytesToEndOfFile(FW_OFile *somSelf, Environment *ev)
  409. {
  410.     FW_SOM_TRY
  411.     {
  412.         return (somSelf->GetLength(ev) - somSelf->GetPosition(ev));
  413.     }
  414.     FW_SOM_CATCH
  415.     return 0;
  416. }
  417.  
  418.  
  419. //----------------------------------------------------------------------------------------
  420. //    FW_OFile__GetPermissions
  421. //  Returns the permissions used to open this file.
  422. //----------------------------------------------------------------------------------------
  423.  
  424. SOM_Scope void  SOMLINK FW_OFile__GetPermissions(FW_OFile *somSelf, Environment *ev,
  425.         FW_SAccessPermission* thePerms)
  426. {
  427. FW_UNUSED(ev);
  428.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  429.  
  430.     *thePerms = somThis->fRep->fPermission;
  431. }
  432.  
  433.  
  434. //----------------------------------------------------------------------------------------
  435. //    FW_OFile__GetFileSpecification
  436. //  Returns a reference to the file.  This routine is primarily used for
  437. //    exception handling.
  438. //----------------------------------------------------------------------------------------
  439.  
  440. SOM_Scope FW_OFileSpecification*  SOMLINK FW_OFile__GetFileSpecification(FW_OFile *somSelf, Environment *ev)
  441. {
  442. FW_UNUSED(ev);
  443.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  444.  
  445.     return somThis->fRep->fFileSpec;
  446. }
  447.  
  448.  
  449. //----------------------------------------------------------------------------------------
  450. //    FW_OFile__GetFileHandle
  451. //  Returns the native platform handle to the file.
  452. //----------------------------------------------------------------------------------------
  453.  
  454. SOM_Scope FW_PlatformFileHandle*  SOMLINK FW_OFile__GetFileHandle(FW_OFile *somSelf, Environment *ev)
  455. {
  456. FW_UNUSED(ev);
  457.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  458.  
  459.     return &somThis->fRep->fFileHandle;
  460. }
  461.  
  462.  
  463. //----------------------------------------------------------------------------------------
  464. //    FW_OFile__IsEqual
  465. //  Equality operator.
  466. //----------------------------------------------------------------------------------------
  467.  
  468. SOM_Scope FW_Boolean  SOMLINK FW_OFile__IsEqual(FW_OFile *somSelf, Environment *ev,
  469.         FW_OFile* theOtherFile)
  470. {
  471.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  472.  
  473.     FW_SOM_TRY
  474.     {
  475.         FW_CPrivFileRep& rep = *somThis->fRep;
  476.         return (rep.fFileHandle == *theOtherFile->GetFileHandle(ev)) 
  477.                 && (rep.fFileSpec->IsSameAs(ev, theOtherFile->GetFileSpecification(ev)));
  478.     }
  479.     FW_SOM_CATCH
  480.     return FALSE;
  481. }
  482.  
  483.  
  484. //----------------------------------------------------------------------------------------
  485. //    FW_OFile__somInit
  486. //----------------------------------------------------------------------------------------
  487.  
  488. SOM_Scope void  SOMLINK FW_OFile__somInit(FW_OFile *somSelf)
  489. {
  490.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  491.  
  492. //    FW_OFile_parent_FW_ORefCount_somInit(somSelf);
  493.  
  494.     somThis->fRep = 0;
  495. }
  496.  
  497.  
  498. //----------------------------------------------------------------------------------------
  499. //    FW_OFile__somUninit
  500. //----------------------------------------------------------------------------------------
  501.  
  502. SOM_Scope void  SOMLINK FW_OFile__somUninit(FW_OFile *somSelf)
  503. {
  504.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  505.  
  506.     FW_SOM_UNINIT_TRY
  507.     {
  508.         FW_SOMEnvironment ev;
  509.         privCloseFile(somSelf, ev);
  510.     
  511.         delete somThis->fRep;
  512.  
  513. //        FW_OFile_parent_FW_ORefCount_somUninit(somSelf);
  514.     }
  515.     FW_SOM_UNINIT_CATCH
  516. }
  517.  
  518.  
  519. //----------------------------------------------------------------------------------------
  520. //    privOpenFile
  521. //
  522. //    Opens the file using the permissions set with SetPermission.  If no permissions were
  523. //    set, it tries to open the file for exclusive access.  If the file is already open,
  524. //    nothing happens.  If any other errors occur, they are thrown as exceptions.
  525. //----------------------------------------------------------------------------------------
  526. static void privOpenFile(FW_OFile *somSelf, Environment *ev, FW_Boolean allowCreate)
  527. {
  528.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  529.     FW_CPrivFileRep& rep = *somThis->fRep;
  530.     FW_PlatformError theError = FW_xNoError;
  531.     unsigned long accessMode = rep.fPermission.fAccess;
  532.     unsigned long denyMode   = rep.fPermission.fDeny;
  533.  
  534. #ifdef FW_BUILD_WIN
  535.     FW_CString fileName;
  536.  
  537.     rep.fFileSpec->GetFullPath(ev, fileName);
  538. #endif
  539.  
  540. #ifdef FW_BUILD_WIN16
  541.     OFSTRUCT Buffer;
  542.     rep.fFileHandle = ::OpenFile((const FW_Char*)fileName, &Buffer, accessMode | denyMode);
  543.     if (rep.fFileHandle == FW_kInvalidAccessHandle)
  544.         theError = Buffer.nErrCode;
  545. #endif
  546.  
  547. #ifdef FW_BUILD_WIN32
  548.     // If we allowCreate, always open the file.  Otherwise, open only if it 
  549.     // already exists.
  550.     long openMode = (allowCreate ? OPEN_ALWAYS : OPEN_EXISTING);
  551.     
  552.     char szFileName[_MAX_PATH];
  553.     fileName.ExportCString(szFileName);
  554.     
  555.     rep.fFileHandle = ::CreateFile(szFileName, 
  556.                                    accessMode, 
  557.                                    denyMode, 
  558.                                    NULL,
  559.                                    openMode, 
  560.                                    FILE_ATTRIBUTE_NORMAL, 
  561.                                    (HANDLE)NULL);
  562.                                
  563.     if (rep.fFileHandle == FW_kInvalidAccessHandle)
  564.         theError = ::GetLastError();
  565. #endif
  566.  
  567. #ifdef FW_BUILD_MAC
  568.     // If we allowCreate, then try creating the file.  If the file already 
  569.     // exists, we will FW_CATCH the attempt to re-create it and merrily roll 
  570.     // along.  If the file does not exist, it will when we're done.
  571.     if (allowCreate)
  572.     {
  573.         FW_TRY
  574.         {
  575.             FW_FileSystem_CreateFile(ev, rep.fFileSpec, FALSE);
  576.         }
  577.         FW_CATCH_BEGIN
  578.         FW_CATCH(FW_XException, theException)
  579.         {
  580.             if (theException.GetPlatformError() != FW_xFileExists)
  581.                 FW_THROW_SAME();
  582.         }
  583.         FW_CATCH_END
  584.  
  585.         // At this point, the file exists (modulo another thread nuking it).
  586.     }
  587.  
  588.     // Check to see if file sharing exists on this volume.  If it does, open the file using
  589.     // deny modes.
  590.     FSSpec theMacSpec;
  591.  
  592.     rep.fFileSpec->MacGetFSSpec(ev, &theMacSpec);
  593.  
  594.     if (FW_FileSystem_MacIsVolumeShared(ev, theMacSpec.vRefNum))
  595.     {
  596.         HParamBlockRec paramBlock;
  597.  
  598.         paramBlock.fileParam.ioNamePtr = (StringPtr) & (theMacSpec.name);
  599.         paramBlock.fileParam.ioVRefNum = theMacSpec.vRefNum;
  600.         paramBlock.fileParam.ioDirID = theMacSpec.parID;
  601.         paramBlock.accessParam.ioDenyModes = accessMode | denyMode;
  602.  
  603.         theError = ::PBHOpenDenySync(¶mBlock);
  604.         rep.fFileHandle = paramBlock.fileParam.ioFRefNum;
  605.     }
  606.     else
  607.         theError = ::FSpOpenDF(&(theMacSpec), accessMode, &rep.fFileHandle);
  608.     
  609. #endif    
  610.     
  611.     FW_FailOnError(theError);
  612. }
  613.  
  614. //----------------------------------------------------------------------------------------
  615. //    privCloseFile
  616. //----------------------------------------------------------------------------------------
  617. static void privCloseFile(FW_OFile *somSelf, Environment *ev)
  618. {
  619. FW_UNUSED(ev);
  620.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  621.     FW_CPrivFileRep& rep = *somThis->fRep;
  622.     FW_PlatformError theError = FW_xNoError;
  623.  
  624. #if 0
  625. //#ifdef FW_BUILD_WIN16
  626.     FW_PlatformFileHandle handle = rep.fFileHandle;
  627.     
  628.     __asm {
  629.         mov        bx, [handle]
  630.         mov        ah, 03Eh
  631.     }
  632.     
  633.     DOS3Call();
  634.         
  635.     __asm {
  636.         jc        _error
  637.         xor        ax, ax
  638.     }
  639.  
  640.     _error:
  641.         
  642.     __asm {
  643.         mov        theError, ax
  644.     }
  645. #endif
  646.  
  647. #ifdef FW_BUILD_WIN32
  648.     if(!::CloseHandle(rep.fFileHandle))
  649.         theError = ::GetLastError();
  650. #endif
  651.  
  652. #ifdef FW_BUILD_MAC
  653.     theError = ::FSClose(rep.fFileHandle);
  654. #endif
  655.  
  656.     FW_FailOnError(theError);
  657.         
  658.     rep.fFileHandle = FW_kInvalidAccessHandle;
  659. }
  660.  
  661.  
  662. #ifdef FW_BUILD_WIN16
  663. //----------------------------------------------------------------------------------------
  664. //    privWinGetIOBufferSize
  665. //----------------------------------------------------------------------------------------
  666. static short privWinGetIOBufferSize(long bytesDesired, const void* buffer)
  667. {
  668.     short offset = (short)(long)buffer;
  669.     long max = 0x10000L - offset;
  670.     if(max > bytesDesired)
  671.         max = bytesDesired;
  672.     return max > 16384 ? 16384 : (short)max;
  673. }
  674.                                        
  675.  
  676. //----------------------------------------------------------------------------------------
  677. //    privWinPrimitiveRead
  678. //----------------------------------------------------------------------------------------
  679. static FW_PlatformError privWinPrimitiveRead(FW_PlatformFileHandle handle,
  680.                                             short bytesToRead,
  681.                                             void* buffer,
  682.                                             short& bytesActuallyRead)
  683. {
  684.     FW_PlatformError theError;
  685.     
  686.     __asm {
  687.         mov        ah, 03Fh
  688.         mov        bx, [handle]
  689.         mov        cx, [bytesToRead]
  690.         push    ds
  691.         lds        dx, [buffer]
  692.     }
  693.     
  694.     DOS3Call();
  695.         
  696.     __asm {
  697.         pop        ds
  698.         jc        _error
  699.         les        bx, [bytesActuallyRead]
  700.         mov        es:[bx], ax
  701.         xor        ax, ax
  702.     }
  703.     
  704.     _error:
  705.     
  706.     __asm {
  707.         mov        theError, ax
  708.     };
  709.     
  710.     return (theError);
  711. }
  712.  
  713.  
  714. //----------------------------------------------------------------------------------------
  715. //    privWinPrimitiveWrite
  716. //----------------------------------------------------------------------------------------
  717. static FW_PlatformError privWinPrimitiveWrite(FW_PlatformFileHandle handle,
  718.                                              short bytesToWrite,
  719.                                              const void* buffer,
  720.                                              short& bytesActuallyWritten)
  721. {
  722.     FW_PlatformError theError;
  723.     
  724.     __asm {
  725.         mov        ah, 040h
  726.         mov        bx, [handle]
  727.         mov        cx, [bytesToWrite]
  728.         push    ds
  729.         lds        dx, [buffer]
  730.     }
  731.     
  732.     DOS3Call();
  733.         
  734.     __asm {
  735.         pop        ds
  736.         jc        _error
  737.         les        bx, [bytesActuallyWritten]
  738.         mov        es:[bx], ax
  739.         xor        ax, ax
  740.     }
  741.     
  742.     _error:
  743.     
  744.     _asm {
  745.         mov        theError, ax
  746.     };
  747.     
  748.     return (theError);
  749. }
  750. #endif
  751.  
  752. //----------------------------------------------------------------------------------------
  753. // privDoRead
  754. //----------------------------------------------------------------------------------------
  755. static void privDoRead(FW_OFile *somSelf, Environment *ev, void* destination, long count)
  756. {
  757. FW_UNUSED(ev);
  758.  
  759.     FW_ASSERT (count >= 0);
  760.     if (count > 0)
  761.     {
  762.         FW_OFileData *somThis = FW_OFileGetData(somSelf);
  763.         FW_CPrivFileRep& rep = *somThis->fRep;
  764.         FW_PlatformError theError = FW_xNoError;
  765.     
  766. #ifdef FW_BUILD_WIN16
  767.         long toRead = count;
  768.         while(toRead > 0)
  769.         {
  770.             short readNow = privWinGetIOBufferSize(toRead, destination);
  771.             short actualRead;
  772.             theError = privWinPrimitiveRead(rep.fFileHandle, readNow, destination, actualRead);
  773.             
  774.             if(theError != 0)
  775.                 break;
  776.                 
  777.             toRead -= actualRead;
  778.     
  779.             if(actualRead < readNow)
  780.                 break;
  781.                 
  782.             destination = ((char __huge*) destination) + toRead;
  783.         }
  784.         
  785.         if (toRead != 0)
  786.             theError = FW_kEndOfFileReached;
  787. #endif
  788.  
  789. #ifdef FW_BUILD_WIN32
  790.         DWORD actualRead;
  791.         if(!::ReadFile(rep.fFileHandle, destination, count, &actualRead, NULL))
  792.             theError = ::GetLastError();
  793. #endif
  794.  
  795. #ifdef FW_BUILD_MAC
  796.         theError = ::FSRead(rep.fFileHandle, &count, destination);
  797. #endif
  798.  
  799.         FW_FailOnError(theError);
  800.     }
  801. }
  802.  
  803.  
  804. //----------------------------------------------------------------------------------------
  805. //    privDoWrite
  806. //----------------------------------------------------------------------------------------
  807. static void privDoWrite(FW_OFile *somSelf, Environment *ev, const void* source, long count)
  808. {
  809. FW_UNUSED(ev);
  810.      FW_ASSERT (count >= 0);
  811.     if (count > 0)
  812.     {
  813.         FW_OFileData *somThis = FW_OFileGetData(somSelf);
  814.         FW_CPrivFileRep& rep = *somThis->fRep;
  815.         FW_PlatformError theError = FW_xNoError;
  816.  
  817. #ifdef FW_BUILD_WIN16
  818.         long toWrite = count;
  819.         while(toWrite > 0)
  820.         {
  821.             short writeNow = privWinGetIOBufferSize(toWrite, source);
  822.             short actualWritten;
  823.             theError = privWinPrimitiveWrite(rep.fFileHandle, writeNow, source, actualWritten);
  824.             
  825.             if(theError != 0)
  826.                 break;
  827.                 
  828.             toWrite -= actualWritten;
  829.     
  830.             if(actualWritten < writeNow)
  831.                 break;
  832.                 
  833.             source = ((const char __huge*) source) + toWrite;
  834.         }
  835.             
  836.         if (toWrite != 0)
  837.             theError = FW_kDiskFull;
  838. #endif
  839.  
  840. #ifdef FW_BUILD_WIN32
  841.         DWORD actualWrite;
  842.         if(!::WriteFile(rep.fFileHandle, source, count, &actualWrite, NULL))
  843.             theError = ::GetLastError();
  844. #endif
  845.  
  846. #ifdef FW_BUILD_MAC
  847.         theError = ::FSWrite(rep.fFileHandle, &count, source);
  848. #endif
  849.  
  850.         FW_FailOnError(theError);
  851.     }
  852. }
  853.  
  854.  
  855. #ifdef FW_BUILD_WIN
  856. //----------------------------------------------------------------------------------------
  857. //    privWinMoveFilePointer
  858. //----------------------------------------------------------------------------------------
  859. static FW_PlatformError privWinMoveFilePointer(FW_OFile *somSelf,
  860.                                                       Environment *ev,
  861.                                                       long markOffset,
  862.                                                       FW_EFS_MoveMethods positioningMode,
  863.                                                       long& newPosition)
  864. {
  865.     FW_OFileData *somThis = FW_OFileGetData(somSelf);
  866.     FW_CPrivFileRep& rep = *somThis->fRep;
  867.     FW_PlatformError theError = FW_xNoError;
  868.  
  869. #ifdef FW_BUILD_WIN16
  870.     FW_PlatformFileHandle handle = rep.fFileHandle;
  871.     
  872.     __asm {
  873.         mov     ax, [positioningMode]
  874.         mov     ah, 42h
  875.         mov        bx, [handle]
  876.         mov     dx, word ptr [markOffset]
  877.         mov     cx, word ptr [markOffset+2]
  878.     }
  879.     
  880.     DOS3Call();
  881.         
  882.     __asm {
  883.         jc        _error
  884.         les     bx, [newPosition]
  885.         mov     word ptr es:[bx], ax
  886.         mov     word ptr es:[bx+2], dx
  887.         xor     ax, ax
  888.     }
  889.             
  890.     _error:
  891.     
  892.     __asm {
  893.         mov        theError, ax
  894.     }
  895. #endif
  896.  
  897. #ifdef FW_BUILD_WIN32
  898.     newPosition = ::SetFilePointer(rep.fFileHandle, markOffset, NULL, positioningMode);
  899.     if (newPosition == FW_kInvalidSeek)
  900.         theError = ::GetLastError();
  901. #endif
  902.  
  903.     return theError;
  904. }
  905. #endif
  906.  
  907.  
  908.